﻿using AJWPFAdmin.Core;
using AJWPFAdmin.Core.Components.ViewModels;
using AJWPFAdmin.Core.Components.Views;
using AJWPFAdmin.Core.Enums;
using AJWPFAdmin.Core.ExtensionMethods;
using AJWPFAdmin.Core.Models.EF.Tables;
using AJWPFAdmin.Core.Utils;
using AJWPFAdmin.Core.Validation;
using AJWPFAdmin.Services.AppointAPI;
using AJWPFAdmin.Services.EF;
using Masuit.Tools;
using Masuit.Tools.Systems;
using Microsoft.EntityFrameworkCore;
using Prism.Commands;
using Prism.Events;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;
using static AJWPFAdmin.Core.ExceptionTool;

namespace EntranceGuardManager.Modules.Main.ViewModels
{
    public class WatchhouseFormViewModel : AnnotationValidationViewModel, IDialogAware
    {
        private string _dialogTitle;
        public string DialogTitle
        {
            get { return _dialogTitle; }
            set { SetProperty(ref _dialogTitle, value); }
        }

        private bool _loading;
        public bool Loading
        {
            get { return _loading; }
            set { SetProperty(ref _loading, value); }
        }

        private Watchhouse _form;

        private string _name;
        [Display(Name = "名称")]
        [Required(ErrorMessage = "{0}必填")]
        [StringLength(50, ErrorMessage = "{0}超长:{1}")]
        public string Name
        {
            get { return _name; }
            set
            {
                SetProperty(ref _name, value);
                SaveCmd.RaiseCanExecuteChanged();
            }
        }

        private string _code;
        [Display(Name = "编号")]
        [Required(ErrorMessage = "{0}必填")]
        [StringLength(50, ErrorMessage = "{0}超长:{1}")]
        [AJFormCodeField(ErrorMessage = "编号格式有误")]
        public string Code
        {
            get { return _code; }
            set
            {
                SetProperty(ref _code, value);
                SaveCmd.RaiseCanExecuteChanged();
            }
        }

        private string _ip;
        [Display(Name = "IP地址")]
        [AJFormIPField]
        public string IP
        {
            get { return _ip; }
            set
            {
                SetProperty(ref _ip, value);
                SaveCmd.RaiseCanExecuteChanged();
            }
        }

        private decimal _longitude;
        /// <summary>
        /// 经度
        /// </summary>
        [Display(Name = "经度")]
        [Range(0, 180, ErrorMessage = "{0}须在 {1} ~ {2} 度之间")]
        public decimal Longitude
        {
            get => _longitude;
            set { SetProperty(ref _longitude, value); SaveCmd.RaiseCanExecuteChanged(); }
        }


        private decimal _latitude;
        /// <summary>
        /// 纬度
        /// </summary>
        [Display(Name = "纬度")]
        [Range(0, 90, ErrorMessage = "{0}须在 {1} ~ {2} 度之间")]
        public decimal Latitude
        {
            get => _latitude;
            set { SetProperty(ref _latitude, value); SaveCmd.RaiseCanExecuteChanged(); }
        }

        private int _passagewaySum;
        [Display(Name = "道闸数量")]
        [AJFormIntegerField(ErrorMessage = "道闸数量有误")]
        public int PassagewaySum
        {
            get { return _passagewaySum; }
            set
            {
                SetProperty(ref _passagewaySum, value);
                SaveCmd.RaiseCanExecuteChanged();
            }
        }



        private string _remark;
        [Display(Name = "备注")]
        [StringLength(100, ErrorMessage = "{0}超长:{1}")]
        public string Remark
        {
            get { return _remark; }
            set
            {
                SetProperty(ref _remark, value);
            }
        }

        private PassagewayDirection? _direction;
        [Display(Name = "进出类型")]
        public PassagewayDirection? Direction
        {
            get { return _direction; }
            set
            {
                SetProperty(ref _direction, value);
            }
        }

        private Dictionary<string, PassagewayDirection> _directionOptions;
        public Dictionary<string, PassagewayDirection> DirectionOptions
        {
            get { return _directionOptions; }
            set
            {
                SetProperty(ref _directionOptions, value);
            }
        }

        private DelegateCommand _saveCmd;
        public DelegateCommand SaveCmd =>
            _saveCmd ?? (_saveCmd = new DelegateCommand(ExecuteSaveCmdAsync, CanExecuteSaveCmd));

        async void ExecuteSaveCmdAsync()
        {
            if (!ValidateModel())
            {
                SaveCmd.RaiseCanExecuteChanged();
                
                AJCommonDialog.ShowDialog(new AJCommonDialogViewModel.AJCommonDialogParams
                {
                    Title = "提示",
                    Message = $"表单校验失败,请检查所填数据",
                    Detail = string.Join(";", ValidationErrorsByProperty.SelectMany(p => p.Value).Select(p => p.ToString()))
                });
                return;
            }

            Loading = true;

            var code = Code;
            _form.IP = IP;
            _form.Name = Name;
            _form.Remark = Remark;
            _form.PassagewaySum = PassagewaySum;
            _form.Latitude = Latitude;
            _form.Longitude = Longitude;
            _form.Direction = Direction;
            if (_form.Id == 0)
            {
                if (db.Watchhouses.Any(p => p.Code == code))
                {
                    ExceptionTool.FriendlyError("进出口编号已存在", dialogId: DialogIds.DialogWindow);
                    return;
                }
                _form.Code = code;
                _form.Id = YitIdHelper.NextId();
                _form.CreateDate = DateTime.Now;
                db.Watchhouses.Add(_form);
            }
            else
            {

                if (_form.Code != code && db.Watchhouses.Any(p => p.Code == code))
                {
                    ExceptionTool.FriendlyError("进出口编号已存在", dialogId: DialogIds.DialogWindow);
                    return;
                }
                _form.Code = code;
                _form.UpdateDate = DateTime.Now;
                db.Entry(_form).State = EntityState.Modified;
            }

            await db.SaveChangesAsync();

            //上传出入口信息
            await _appointSvc.API.UploadEntGateInfoAsync(new WatchhouseInfoParams
            {
                Watchhouse = _form
            });

            Loading = false;

            RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
        }

        bool CanExecuteSaveCmd()
        {
            return !HasErrors;
        }

        public string Title => string.Empty;

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {

        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            parameters.TryGetValue<Watchhouse>("data", out var data);

            parameters.TryGetValue<MaterialType>("type", out var type);

            if (data != null)
            {
                _form = data;

                Name = _form.Name;
                Code = _form.Code;
                IP = _form.IP;
                Remark = _form.Remark;
                PassagewaySum = _form.PassagewaySum;
                Longitude=_form.Longitude;
                Latitude= _form.Latitude;
                Direction = _form.Direction;
            }

            DialogTitle = data == null ? $"新增进出口" : $"编辑 {data.Name}";
        }

        private DbService db;
        private AJGlobalExceptionResolvedEvent _globalExceptionEvt;
        private AppointAPISvc _appointSvc;
        public WatchhouseFormViewModel(DbService dbIns, AppointAPISvc appointAPISvc, IEventAggregator eventAggregator)
        {
            _form = new Watchhouse();
            _appointSvc = appointAPISvc;
            _globalExceptionEvt = eventAggregator.GetEvent<AJGlobalExceptionResolvedEvent>();
            _globalExceptionEvt.Subscribe(() =>
            {
                Loading = false;
            });
            db = dbIns;
            DirectionOptions = CommonUtil.EnumToDictionary<PassagewayDirection>(null);
        }
    }
}
